package com.myblog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.myblog.constant.RedisHashKey;
import com.myblog.constant.RedisKey;
import com.myblog.mapper.*;
import com.myblog.model.Visitor;
import com.myblog.redis.RedisService;
import com.myblog.service.impl.redis.HashRedisServiceImpl;
import com.myblog.utils.DataMap;
import com.myblog.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit;


@Service
public class RedisServiceImpl implements RedisService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private VisitorMapper visitorMapper;

    @Autowired
    private HashRedisServiceImpl hashRedisService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private LeaveMapper leaveMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Override
    public void expire(String key, long time, TimeUnit timeUnit) {
        hashRedisService.expire(key,time,timeUnit);
    }

    @Override
    public Visitor visitorMsgIfExist(Object visitorNum, String pageName) {
        Visitor visitor = new Visitor();
        //如果存在，将数据读出
        if (visitorNum != null) {
            visitor.setPageName(pageName);
            visitor.setVisitorNum(Long.parseLong((String) visitorNum));
        } else {
            //如果不存在键值对，从数据库中查找
            visitor = visitorMapper.selectVisitorNumByPageName(pageName);
            //如果数据库中不存在
            if (!pageName.equals(RedisHashKey.TOTAL_VISITOR)) {
                if (visitor == null) {
                    visitorMapper.insertVisitor(0, pageName);
                    visitor = visitorMapper.selectVisitorNumByPageName(pageName);
                }
                //写入redis
                hashRedisService.put(StringUtil.VISITOR, pageName, Long.toString(visitor.getVisitorNum()));
//            redisTemplate.opsForHash().put(StringUtil.VISITOR,pageName, Long.toString(visitor.getVisitorNum()));
                //设置redis存活时间，节约内存空间
//            redisTemplate.expire(StringUtil.VISITOR,REDIS_SURVIVE, TimeUnit.SECONDS);
            }
            //如果pageName为totalVisitor，则通过数据库中的数据查找得到visitorNum
            else {
                if (visitor == null) {
                    Integer NumOfTotalVisitor = visitorMapper.selectTotalVisitorNumByOthers();
                    visitorMapper.insertVisitor(NumOfTotalVisitor, pageName);
                    visitor = visitorMapper.selectVisitorNumByPageName(pageName);
                }
                //写入redis
                hashRedisService.put(StringUtil.VISITOR, pageName, Long.toString(visitor.getVisitorNum()));
            }
        }
        return visitor;
    }


    @Override
    public void updateVisitorNum(Visitor visitor, Visitor totalVisitor) {
        //该页面访问次数+1
        visitor.setVisitorNum(visitor.getVisitorNum() + 1);
        //总访问次数+1
        totalVisitor.setVisitorNum(totalVisitor.getVisitorNum() + 1);

        //将更新了之后的数据重新写入redis
        //更新当前页面的访客量
        hashRedisService.put(StringUtil.VISITOR, visitor.getPageName(), Long.toString(visitor.getVisitorNum()));
        //更新总访客量
        hashRedisService.put(StringUtil.VISITOR, RedisHashKey.TOTAL_VISITOR, Long.toString(totalVisitor.getVisitorNum()));
//        redisTemplate.opsForHash().put(StringUtil.VISITOR ,visitor.getPageName(),Long.toString(visitor.getVisitorNum()));
//
//        redisTemplate.opsForHash().put(StringUtil.VISITOR ,TOTAL_VISITOR,Long.toString(totalVisitor.getVisitorNum()));
//
        //设置redis存活时间，节约内存空间
//        redisTemplate.expire(StringUtil.VISITOR,REDIS_SURVIVE,TimeUnit.SECONDS);
    }


    @Override
    public Object getHash(String key, Object field) {
        return hashRedisService.get(key, field);
    }


    @Override
    public Integer numOfAllUserIfExist(Object allUser) {
        Integer numOfUser = 0;
        //如果redis中存在文章总量数据，直接返回
        if (allUser != null) {
            return Integer.parseInt(allUser.toString());
        }
        //如果不存在，从数据库中查找
        numOfUser = userMapper.selectNumOfUser();
        if (numOfUser == 0) {
            return 0;
        }
        //写入redis
        hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ALL_USER, numOfUser);

        //设置过期时间
//        redisTemplate.expire(STATISTICS,REDIS_SURVIVE,TimeUnit.SECONDS);
        return numOfUser;
    }


    @Override
    public Integer numOfAllArticleIfExist(Object articleNum) {
        Integer numOfArticle = 0;
        //如果redis中存在文章总量数据，直接返回
        if (articleNum != null) {
            return Integer.parseInt(articleNum.toString());
        }
        //如果不存在，从数据库中查找
        numOfArticle = articleMapper.selectNumOfArticle();
        if (numOfArticle == 0) {
            return 0;
        }
        //写入redis
        hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ARTICLE_NUM, numOfArticle);

        //设置过期时间
//        redisTemplate.expire(STATISTICS,REDIS_SURVIVE,TimeUnit.SECONDS);
        return numOfArticle;
    }


    @Override
    public Integer numOfAllArticleLikeIfExist(Object articleLikeNum) {
        Integer numOfArticleLike = 0;
        //如果redis中存在文章总量数据，直接返回
        if (articleLikeNum != null) {
            return Integer.parseInt(articleLikeNum.toString());
        }
        //如果不存在，从数据库中查找
        numOfArticleLike = articleMapper.selectNumOfArticleLike();
        if (numOfArticleLike == 0) {
            return 0;
        }
        //写入redis
        hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ARTICLE_LIKE_NUM, numOfArticleLike);

        //设置过期时间
//        redisTemplate.expire(STATISTICS,REDIS_SURVIVE,TimeUnit.SECONDS);
        return numOfArticleLike;
    }


    @Override
    public Integer numOfArticleLikeByIdIfExist(Object articleLikeNum, long articleId) {
        Integer numOfArticleLike = 0;
        //如果redis中存在文章数据，直接返回
        if (articleLikeNum != null) {
            return Integer.parseInt(articleLikeNum.toString());
        } else {//如果不存在，从数据库中查找
            numOfArticleLike = articleMapper.selectArticleLikesByArticleId(articleId);
        }
        //写入redis
        hashRedisService.put(RedisKey.ARTICLE, RedisHashKey.ARTICLE_LIKE_NUM, numOfArticleLike);

        //设置过期时间
//        redisTemplate.expire(STATISTICS,REDIS_SURVIVE,TimeUnit.SECONDS);
        return numOfArticleLike;
    }


    @Override
    public void updateNumOfAllArticleNum(Integer numOfTheArticle) {
        hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ARTICLE_NUM, numOfTheArticle);
    }


    @Override
    public void updateNumOfAllUserNum(Integer numOfTheUser) {
        hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ALL_USER, numOfTheUser);
    }


    @Override
    public void updateThumbsUpOnRedis(int i) {
        //从redis中获取文章新增点赞信息
        boolean articleThumbsUpOnRedisIfExist = hashRedisService.hasHashKey(RedisKey.STATISTICS, RedisHashKey.ARTICLE_LIKE_NUM);
        //判断总点赞信息是否存在，不存在则去数据库中查找
        if (!articleThumbsUpOnRedisIfExist) {
            hashRedisService.put(RedisKey.STATISTICS, RedisHashKey.ARTICLE_LIKE_NUM, 1);
        } else {
            hashRedisService.hashIncrement(RedisKey.STATISTICS, RedisHashKey.ARTICLE_LIKE_NUM, i);
        }
    }

    @Override
    public DataMap getUserNews(String userPhone) {
        //封装信息
        HashMap<String,Object> result = new HashMap<>();
        //根据用户phone查找用户id
        Integer userId = userMapper.selectUserIdByPhone(userPhone);
        LinkedHashMap allMsg = (LinkedHashMap) hashRedisService.getAllFieldAndValue(String.valueOf(userId));

        if(allMsg.size() == 0){
            //根据用户id从数据库中获取未读评论数量
            Integer leaveMessageNum = leaveMapper.selectNotReadNumByRespondentId(userId);
            //根据用户id从数据库中获取未读留言数量
            Integer commentNum = commentMapper.selectNotReadNumByRespondentId(userId);
            //根据两个未读信息计算总未读
            Integer allNewsNum = leaveMessageNum + commentNum;
            hashRedisService.put(String.valueOf(userId),"allNewsNum",allNewsNum);
            hashRedisService.put(String.valueOf(userId),"commentNum",commentNum);
            hashRedisService.put(String.valueOf(userId),"leaveMessageNum",leaveMessageNum);
            redisService.expire(String.valueOf(userId),RedisHashKey.REDIS_SURVIVE_TIME,TimeUnit.SECONDS);
            allMsg = (LinkedHashMap) hashRedisService.getAllFieldAndValue(String.valueOf(userId));
        }
        int aliNewsNum = (int)allMsg.get("allNewsNum");
        int commentNum = (int)allMsg.get("commentNum");
        int leaveMessageNum = (int)allMsg.get("leaveMessageNum");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("allNewsNum",aliNewsNum);
        jsonObject.put("commentNum",commentNum);
        jsonObject.put("leaveMessageNum",leaveMessageNum);
        result.put("result",jsonObject);
        return DataMap.success().setData(result);
    }

    @Override
    public void deleteHahKey(String key){
        hashRedisService.hashKeyDelete(key);
    }



}
